3 Hardware debugging allows debugging the firmware with GDB, including most of its
4 features that you can find while debugging software for a computer like setting
5 breakpoins or printing variables or stepping through the code.
7 Additionally, firmware can also be flashed directly either from the IDE or from GDB,
8 significanly reducing the time required for the compile/flash/test cycle.
12 Although more complex and expensive solutions exists, an STLink V2 clone will let you
13 use all the features of hardware debugging. They can be purchased on any of the typical
16 [ST Link V2 Clone](https://inavflight.com/shop/s/bg/1177014)
17 [Original ST Link V2](https://inavflight.com/shop/s/bg/1099119)
19 Additionally, most nucleo boards from ST come with a brekable part that contains an
20 STLink V2.1 or V3. These can also be used to debug an FC, but can be more difficult to
23 To connect it a flight controller, you need to locate the SWDIO and SWCLK pins from the
24 MCU. These correspond to PA13 (SWDIO) and PA14 (SWCLK). Be aware that not all manufacturers
25 break out these pins, but a lot of them put them in small pads available somewhere.
26 Connect SWDIO, SWCLK and GND from the FC to pins with the FC
28 TODO: Add pictures of several FCs with SWDIO and SWCLK highlighted.
32 Besides an ARM toolchain, [OpenOCD](http://openocd.org) is required. Note that at the
33 time of this writing, OpenOCD hasn't had a release in almost 3 years, so you might
34 need to look for unofficial releases or compile from source.
36 [stlink](https://github.com/texane/stlink), while not strictly required, can be handy
37 for quickly testing the SWD connection or flashing or erasing. To avoid ambiguities
38 between the hardware and the software, the former will be referred as `ST Link` while
39 we'll use `stlink` for the latter.
41 Please, follow the installation instructions for your operating system.
45 Install the Windows Subsystem for Linux, then follow the Linux instructions.
49 Install [Homebrew](https://brew.sh) (a package manager) first.
51 To install OpenOCD type `brew install open-ocd --HEAD` in a terminal. Note the `--HEAD`
54 For stlink, use `brew install stlink`.
58 Install [Homebrew for Linux](https://docs.brew.sh/Homebrew-on-Linux), since versions
59 provided by your distro's package manager might be out of date. Homebrew can cohexist
60 with your existing package manager without any problems.
62 Then, follow the same instructions for installing OpenOCD and stlink for macOS.
66 Connect SWDIO and SWCLK from the FC to pins with the same label on the ST Link. You must
67 also connect one of the GND from FC to any of the GND pins to the ST Link. Note the
70 - There are several ST Link clone types with different pinouts. Pay attention to the pin
72 - In some ST Link clones, some GND pins are actually floating and not connected to
73 - anything. Use a multimeter to check the GND pins and use any of the valid ones.
74 - Even if you're powering everything from the same computer, make sure to directly connect
75 the grounds from the FC to the ST Link. Some FC/stlink combinations have a 0.1-0.2V
76 difference between their grounds and if you don't connect them, stlink won't work.
78 The FC can be powered by any power source that it supports (battery, USB, etc...), just
79 make sure to not connect power from the ST Link (the pins labelled as 3.3V and 5V) to the
80 FC if something else is powering it.
82 Once you're wired everything, test the connections with a DMM before applying power. Then
83 power both the FC and the stlink (the order doesn't matter) and run `st-info --probe`
84 You should see something like:
87 Found 1 stlink programmers
88 serial: 0d0d09002a12354d314b4e00
89 openocd: "\x0d\x0d\x09\x00\x2a\x12\x35\x4d\x31\x4b\x4e\x00"
90 flash: 524288 (pagesize: 16384)
93 descr: F4 device (low power) - stm32f411re
96 ## Compilation options
98 INAV is compiled with debug symbols by default, since they're only stored in the locally
99 generated `.elf` file and they never use flash space in the target. However, some
100 optimizations like inlining and LTO might rearrange some sections of the code enough
101 to interfere with debugging. All compile time optimizations can be disabled by
102 using `DEBUG=GDB` when calling `make`.
104 You may find that if you compile all the files without optimizations the program might
105 too big to fit on the target device. In that case, one of the possible solutions is
106 compiling all files with optimization (`make clean`, `make ...`) first, then re-save
107 or `touch` the files you want to be able to step though and then run `make DEBUG=GDB`.
108 This will then re-compile the files you're interested in debugging with debugging symbols and you will get a smaller binary file which should then fit on the device.
112 To run a debug session, you will need two terminal windows. One will run OpenOCD, while
113 the other one will run gdb.
115 Although not strictly required, it is recommended to set the target you're working on
116 in `make/local.mk` (create it if it doesn't exist), by adding a line like e.g.
117 `TARGET ?= SOME_VALID_TARGET`. This way you won't need to specify the target name in
120 From one of the terminals, type `make openocd-run`. This will start OpenOCD and connect
121 to the MCU. Leave OpenOCD running in this terminal.
123 From another terminal, type `make gdb-openocd`. This will compile the `.elf` binary for
124 the current target and start `gdb`. From there you will usually want to execute the gdb
125 `load` command first, which will flash the binary to the target. Once it finishes, start
126 running it by executing the `continue` command.
128 For conveniency, you can invoke `make gdb-openocd` with the environment variable `$LOAD`
129 set to a non-empty string (e.g. `LOAD=1 make gdb-openocd`), which will run the `load`
130 command and flash the target as soon as gdb connects to it.
132 From there on, you can use any gdb commands like `b` for setting breakpoints, `p` for
133 printing, etc... Check a gdb tutorial for more details if you're not already familiar
136 ### Rebuilding and reflashing
138 To rebuild, flash and rerun the binary after doing any modifications, recompile it
139 with `make`, then press `control+c` to interrupt gdb. Halt the target by entering the
140 gdb command `monitor reset halt` and then type `load` to flash it. gdb will notice the
141 binary has changed and re-read the debug symbols. Then you can restart the firmware with
142 `continue`. This way, you can very quickly flash, upload and test since neither OpenOCD
143 nor gdb need to be restarted.
147 By default, the Makefiles will assume an ST Link v2, which is the version found in the
148 popular and cheap clones. However, other versions are also supported. Just set the
149 `STLINK` environment variable (either via command line or either via `local.mk`) to
150 `1` or `2` or `2.1`, according to your hardware.
154 Semihosting is an ARM feature that allows printing messages via the SWD connection.
155 The logging framework inside INAV can output its messages via semihosting. To enable
156 it, make sure you've deleted all generated files (e.g. `make clean`) and set the
157 environment variable `$SEMIHOSTING` to a non-empty string, either via command line
158 or via `local.mk`. Once you start the target, log messages will appear on the openocd
159 terminal. Note that even with semihosting enabled, logging has be explicitely enabled